class Scheduler {
  constructor(max) {
    this.max = max
    this.count = 0; // 用来记录当前正在执行的异步函数
    this.queue = new Array() // 表示等待队列
  }

  async add(promiseCreator) {
    if (this.count >= this.max) {
      await new Promise((resolve, reject) => this.queue.push(resolve))
    }

    this.count++;
    let res = await promiseCreator()
    this.count--
    if (this.queue.length) {
      // 依次唤醒add
      // 若队列中有值，将其resolve弹出，并执行
      // 以便阻塞的任务，可以正常执行
      this.queue.shift()()
    }
    return res
  }
}

const timeout = time => new Promise(resolve => {setTimeout(resolve, time);});

const scheduler = new Scheduler(2);

const addTask = (time, order) => {
  //add返回一个promise，参数也是一个promise
  scheduler.add(() => timeout(time)).then(() => console.log(order));
};
  
addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');

// output: 2 3 1 4 
// 1,2 先加入多列执行，等到 500ms后 3 加入队列，等3执行完成 1还没有执行完成，4 加入队列，此时 1还有200ms 执行完成，4还有400ms执行完成